import auth from "@/plugins/auth.ts";
import router, { constantRoutes, dynamicRoutes } from "@/router";
import { getRouters } from "@/api/menu.ts";
import Layout from "@/views/system/layout/HSB/index.vue";
import ParentView from "@/views/system/layout/ParentView/index.vue";
import InnerLink from "@/views/system/layout/InnerLink/index.vue";
import { defineStore } from "pinia";
import type { RouteRecordRaw } from "vue-router";

// 匹配 views 里面所有的 .vue 文件
const modules = import.meta.glob("./../../views/**/*.vue");
export interface AppCustomRoute {
  path: string;
  name?: string;
  redirect?: string;
  component?: string; // 后端给的字符串
  meta?: Record<string, never>;
  children?: AppCustomRoute[];
  permissions?: string[];
  roles?: string[];
}

// ----------------------
// 类型定义
// ----------------------
export interface AppRouteRecordRaw extends Omit<RouteRecordRaw, "component" | "children"> {
  component?: string | (() => Promise<unknown>);
  children?: AppRouteRecordRaw[];
  permissions?: string[];
  roles?: string[];
}

interface PermissionState {
  routes: RouteRecordRaw[];
  addRoutes: RouteRecordRaw[];
  defaultRoutes: RouteRecordRaw[];
  topbarRouters: RouteRecordRaw[];
  sidebarRouters: RouteRecordRaw[];
}

// ----------------------
// Pinia Store
// ----------------------
const usePermissionStore = defineStore("permission", {
  state: (): PermissionState => ({
    routes: [],
    addRoutes: [],
    defaultRoutes: [],
    topbarRouters: [],
    sidebarRouters: [],
  }),
  actions: {
    setRoutes(routes: RouteRecordRaw[]) {
      this.addRoutes = routes;
      this.routes = constantRoutes.concat(routes);
    },
    setDefaultRoutes(routes: RouteRecordRaw[]) {
      this.defaultRoutes = constantRoutes.concat(routes);
    },
    setTopbarRoutes(routes: RouteRecordRaw[]) {
      this.topbarRouters = routes;
    },
    setSidebarRouters(routes: RouteRecordRaw[]) {
      this.sidebarRouters = routes;
    },
    async generateRoutes(roles: string[]): Promise<RouteRecordRaw[]> {
      const res = await getRouters();
      const sdata: AppCustomRoute[] = JSON.parse(JSON.stringify(res.data));
      const rdata: AppCustomRoute[] = JSON.parse(JSON.stringify(res.data));
      const defaultData: AppCustomRoute[] = JSON.parse(JSON.stringify(res.data));

      const sidebarRoutes = filterAsyncRouter(sdata);
      const rewriteRoutes = filterAsyncRouter(rdata, false, true);
      const defaultRoutes = filterAsyncRouter(defaultData);

      const asyncRoutes = filterDynamicRoutes(dynamicRoutes as AppCustomRoute[]);
      asyncRoutes.forEach((route) => {
        router.addRoute(route as unknown as RouteRecordRaw);
      });

      this.setRoutes(rewriteRoutes);
      this.setSidebarRouters(constantRoutes.concat(sidebarRoutes));
      this.setDefaultRoutes(sidebarRoutes);
      this.setTopbarRoutes(defaultRoutes);

      return rewriteRoutes;
    },
  },
});

// ----------------------
// 工具函数
// ----------------------

// 遍历后台传来的路由字符串，转换为组件对象
function filterAsyncRouter(
  asyncRouterMap: AppRouteRecordRaw[],
  lastRouter: AppRouteRecordRaw | false = false,
  type = false
): RouteRecordRaw[] {
  return asyncRouterMap.filter((route: any) => {
    if (type && route.children) {
      route.children = filterChildren(route.children);
    }
    if (route.component) {
      // Layout ParentView InnerLink 特殊处理
      if (route.component === "Layout") {
        route.component = Layout;
      } else if (route.component === "ParentView") {
        route.component = ParentView;
      } else if (route.component === "InnerLink") {
        route.component = InnerLink;
      } else {
        route.component = loadView(route.component as string);
      }
    }
    if (route.children != null && route.children.length) {
      route.children = filterAsyncRouter(route.children, route, type);
    } else {
      delete route.children;
      delete route.redirect;
    }
    return true;
  }) as RouteRecordRaw[];
}

function filterChildren(
  childrenMap: AppRouteRecordRaw[],
  lastRouter: AppRouteRecordRaw | false = false
): AppRouteRecordRaw[] {
  let children: AppRouteRecordRaw[] = [];
  childrenMap.forEach((el) => {
    el.path = lastRouter ? `${lastRouter.path}/${el.path}` : el.path;
    if (el.children && el.children.length && el.component === "ParentView") {
      children = children.concat(filterChildren(el.children, el));
    } else {
      children.push(el);
    }
  });
  return children;
}

// 动态路由遍历，验证是否具备权限
export function filterDynamicRoutes(routes: AppRouteRecordRaw[]): AppRouteRecordRaw[] {
  const res: AppRouteRecordRaw[] = [];
  routes.forEach((route: any) => {
    if (route.permissions) {
      if (auth.hasPermiOr(route.permissions)) {
        res.push(route);
      }
    } else if (route.roles) {
      if (auth.hasRoleOr(route.roles)) {
        res.push(route);
      }
    }
  });
  return res;
}

export const loadView = (view: string): (() => Promise<unknown>) | undefined => {
  let res: (() => Promise<unknown>) | undefined;
  for (const path in modules) {
    const dir = path.split("views/")[1].split(".vue")[0];
    if (dir === view) {
      res = () => modules[path]();
    }
  }
  return res;
};

export default usePermissionStore;
